package com.biodiv.miracle.web.handler;

import com.biodiv.miracle.web.interceptor.HandlerInterceptor;
import jakarta.annotation.Nullable;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @Author: tianquan
 * @CreateTime: 2025-05-26  16:49
 * @Description: 执行链
 */
public class HandlerExecutionChain {
    private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
    private final Object handler;
    private List<HandlerInterceptor> interceptorList;
    private HandlerInterceptor[] interceptorCache;

    public HandlerExecutionChain(Object handler, List<HandlerInterceptor> interceptorList) {
        this.interceptorList = interceptorList;
        interceptorCache = interceptorList.toArray(new HandlerInterceptor[0]);
        this.handler = handler;
    }

    public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (interceptorList != null) {
            HandlerInterceptor[] interceptors = getInterceptors();
            // 循环执行拦截器
            for (HandlerInterceptor interceptor : interceptors) {
                if (!interceptor.preHandle(request, response, handler)) {
                    logger.debug("PreHandle returned false is " + interceptor.getClass().getName());
                    // 拦截器返回false，则执行afterCompletion清除资源
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
            }
        }
        return true;
    }

    public void applyPostHandle(HttpServletRequest request, HttpServletResponse response, Object result) throws Exception {
        if (interceptorList != null) {
            // 反过来 循环执行拦截器
            HandlerInterceptor[] interceptors = getInterceptors();
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response,handler, result);
            }
        }
    }

    public void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
        if (interceptorList != null) {
            // 反过来 循环执行拦截器
            HandlerInterceptor[] interceptors = getInterceptors();
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.afterCompletion(request, response, handler, ex);
            }
        }
    }

    public void setInterceptorList(List<HandlerInterceptor> interceptorList) {
        this.interceptorList = interceptorList;
        if (interceptorList != null) {
            this.interceptorCache = interceptorList.toArray(new HandlerInterceptor[0]);
        }else {
            interceptorCache = new HandlerInterceptor[0];
        }
    }

    public Object getHandler() {
        return this.handler;
    }

    public HandlerInterceptor[] getInterceptors() {
        return interceptorCache;
    }

}
